home *** CD-ROM | disk | FTP | other *** search
- /*
- * purge.c --
- * the POSTGRES purge command.
- *
- * Note:
- * XXX There are many instances of int32 instead of ...Time. These
- * should be changed once it is decided the signed'ness will be.
- */
-
- #include "tmp/c.h"
-
- RcsId("$Header: /private/postgres/src/commands/RCS/purge.c,v 1.16 1992/06/18 18:16:11 mer Exp $");
-
- #include "access/ftup.h"
- #include "access/heapam.h"
- #include "access/tqual.h" /* for NowTimeQual */
- #include "catalog/catname.h"
- #include "utils/fmgr.h"
- #include "utils/log.h"
- #include "utils/nabstime.h"
-
- #include "catalog/pg_relation.h"
-
- static char cmdname[] = "RelationPurge";
-
- #define RELATIVE 01
- #define ABSOLUTE 02
-
- int32
- RelationPurge(relationName, absoluteTimeString, relativeTimeString)
- Name relationName;
- char *absoluteTimeString, *relativeTimeString;
- {
- register i;
- AbsoluteTime absoluteTime = InvalidTime;
- RelativeTime relativeTime = InvalidTime;
- bits8 dateTag;
- Relation relation;
- HeapScanDesc scan;
- static ScanKeyEntryData key[1] = {
- { 0, RelationNameAttributeNumber, F_CHAR16EQ }
- };
- Buffer buffer;
- HeapTuple newTuple, oldTuple;
- Time currentTime;
- char *values[RelationRelationNumberOfAttributes];
- char nulls[RelationRelationNumberOfAttributes];
- char replace[RelationRelationNumberOfAttributes];
-
- Assert(NameIsValid(relationName));
- /* XXX check: pg_user.usecatupd permission? */
-
- if (PointerIsValid(absoluteTimeString)) {
- if (!isabstime(absoluteTimeString, NULL)) {
- elog(NOTICE, "%s: bad absolute time string \"%s\"",
- cmdname, absoluteTimeString);
- absoluteTimeString[0] = '\0';
- elog(WARN, "purge not executed");
- }
- absoluteTime = (int32) nabstimein(absoluteTimeString);
- absoluteTimeString[0] = '\0';
- }
-
- #ifdef PURGEDEBUG
- elog(DEBUG, "RelationPurge: absolute time `%s' is %d.",
- absoluteTimeString, absoluteTime);
- #endif /* defined(PURGEDEBUG) */
-
- if (PointerIsValid(relativeTimeString)) {
- if (isreltime(relativeTimeString, NULL, NULL, NULL) != 1) {
- elog(WARN, "%s: bad relative time string \"%s\"",
- cmdname, relativeTimeString);
- }
- relativeTime = reltimein(relativeTimeString);
-
- #ifdef PURGEDEBUG
- elog(DEBUG, "RelationPurge: relative time `%s' is %d.",
- relativeTimeString, relativeTime);
- #endif /* defined(PURGEDEBUG) */
- }
-
- /*
- * Find the RELATION relation tuple for the given relation.
- */
- relation = heap_openr(RelationRelationName->data);
- key[0].argument = NameGetDatum(relationName);
- fmgr_info(key[0].procedure, &key[0].func, &key[0].nargs);
-
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, (ScanKey) key);
- oldTuple = heap_getnext(scan, 0, &buffer);
- if (!HeapTupleIsValid(oldTuple)) {
- heap_endscan(scan);
- heap_close(relation);
- elog(WARN, "%s: no such relation: %s", cmdname, relationName);
- return(0);
- }
-
- /*
- * Dig around in the tuple.
- */
- currentTime = GetCurrentTransactionStartTime();
- if (!TimeIsValid(relativeTime)) {
- dateTag = ABSOLUTE;
- if (!TimeIsValid(absoluteTime))
- absoluteTime = currentTime;
- } else if (!TimeIsValid(absoluteTime))
- dateTag = RELATIVE;
- else
- dateTag = ABSOLUTE | RELATIVE;
- if (!assertConsistentTimes(absoluteTime, relativeTime, currentTime,
- dateTag, oldTuple)) {
- heap_endscan(scan);
- heap_close(relation);
- elog(WARN, "%s: inconsistent times", cmdname);
- return(0);
- }
- for (i = 0; i < RelationRelationNumberOfAttributes; ++i) {
- nulls[i] = ' ';
- values[i] = NULL;
- replace[i] = ' ';
- }
- if (dateTag & ABSOLUTE) {
- values[RelationExpiresAttributeNumber-1] =
- (char *) absoluteTime;
- replace[RelationExpiresAttributeNumber-1] = 'r';
- }
- if (dateTag & RELATIVE) {
- values[RelationPreservedAttributeNumber-1] =
- (char *) relativeTime;
- replace[RelationPreservedAttributeNumber-1] = 'r';
- }
-
- /*
- * Change the RELATION relation tuple for the given relation.
- */
- newTuple = heap_modifytuple(oldTuple, buffer, relation, values,
- nulls, replace);
-
- /* XXX What do you do with a RuleLock?? */
- /* XXX How do you detect an insertion error?? */
- heap_replace(relation, &newTuple->t_ctid, newTuple);
- pfree(newTuple);
-
- heap_endscan(scan);
- heap_close(relation);
- return(1);
- }
-
-
- assertConsistentTimes(absoluteTime, relativeTime, currentTime, dateTag, tuple)
- Time absoluteTime, relativeTime, currentTime;
- bits8 dateTag;
- HeapTuple tuple;
- {
- Time currentExpires, currentPreserved;
- bool absError = false, relError = false;
-
- currentExpires =
- ((RelationTupleForm) GETSTRUCT(tuple))->relexpires;
- currentPreserved =
- ((RelationTupleForm) GETSTRUCT(tuple))->relpreserved;
- if (dateTag & ABSOLUTE) {
- absError = true;
- if (TimeIsValid(currentExpires) &&
- TimeIsBefore(absoluteTime, currentExpires)) {
- elog(NOTICE,
- "%s: expiration %s before current expiration %d",
- cmdname, absoluteTime, currentExpires);
- } else if (TimeIsValid(currentPreserved) &&
- TimeIsBefore(absoluteTime,
- currentTime + currentPreserved)) {
- elog(NOTICE,
- "%s: expiration %d before current relative %d",
- cmdname, absoluteTime, currentPreserved);
- } else if (AbsoluteTimeIsAfter(absoluteTime, currentTime)) {
- elog(NOTICE,
- "%s: expiration %d after current time %d",
- cmdname, absoluteTime, currentTime);
- } else
- absError = false;
- }
- if (dateTag & RELATIVE) {
- relError = true;
- if (TimeIsValid(currentExpires) &&
- TimeIsBefore(currentTime + relativeTime,
- currentExpires)) {
- elog(NOTICE,
- "%s: relative %d before current expiration %d",
- cmdname, relativeTime, currentExpires);
- } else if (TimeIsValid(currentPreserved) &&
- TimeIsBefore(relativeTime, currentPreserved)) {
- /*
- * XXX handle this by modifying both relative and
- * current times.
- */
- elog(NOTICE,
- "%s: relative %d before current relative %d",
- cmdname, relativeTime, currentPreserved);
- } else
- relError = false;
- }
- /* XXX there must be cases when both are set and they interact... */
- return(!(absError || relError));
- }
-